import hashlib
from datetime import datetime, timezone, timedelta
from django.db import transaction
from rest_framework import viewsets, status, views
from rest_framework.response import Response

from dj_mall import settings
from manage.authentication import JWTAuth
from manage.models.system import User, UserRole
from manage.permission import CustomPermission
from manage.serializers.system import UserSerializer
import jwt


class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    authentication_classes = [JWTAuth]
    # 自定义权限控制类实现权限控制
    permission_classes = [CustomPermission]
    # 自定义权限代码: 属性名为接口方法的名称, 属性值为保存在权限数据表中的接口权限代码
    rbac_permissions = {
        'list': 'user:list',
        'retrieve': 'user:detail',
        'create': 'user:create',
        'update': 'user:update',
        'partial_update': 'user:update',
        'destroy': 'user:destroy'
    }

    def perform_create(self, serializer):
        # 显式启用事务, 如果任何一个环节出错, 则会自动执行事务回滚
        with transaction.atomic():
            # 取出role_id参数
            role_id = serializer.validated_data.pop('role_id')
            # serializer.validated_data: 获取验证过的表单数据
            # 对密码进行加密
            serializer.validated_data['password'] = hashlib.md5(
                serializer.validated_data.get('password').encode()).hexdigest()
            # 执行默认保存
            user = serializer.save()
            if user:
                # 向user_role数据表中写入数据
                for item in role_id:
                    UserRole.objects.create(user=user, role_id=item)

    #   重写更新方法
    def perform_update(self, serializer):
        # 手动开启事务
        with transaction.atomic():
            # 取出role_id参数
            role_id = serializer.validated_data.pop('role_id')
            # 对密码进行加密
            password = serializer.validated_data.get('password')
            serializer.validated_data['password'] = hashlib.md5(password.encode()).hexdigest()
            user = serializer.save()
            if user:
                print(user, 'user')
                for item in role_id:
                    # 更新或者创建
                    role = UserRole.objects.update_or_create(user=user, role_id=item)
                    print(role, 'role')


# 账号登录
class UserLogin(views.APIView):
    def post(self, request):
        # 接收账号和密码
        username = request.data.get('username')
        password = request.data.get('password')
        if not username or not password:
            return Response(data={'detail': '缺少关键参数username或者password'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            auth_user = User.objects.get(username=username)
            if not auth_user:
                return Response(data={'detail': '账号不存在'}, status=status.HTTP_400_BAD_REQUEST)
            if auth_user.password != hashlib.md5(password.encode('utf-8')).hexdigest():
                return Response(data={'detail': '密码错误'}, status=status.HTTP_400_BAD_REQUEST)
            if auth_user.status == 0:
                return Response(data={'detail': '账号已禁用'}, status=status.HTTP_400_BAD_REQUEST)
            serializer = UserSerializer(auth_user)
            payload = {
                'user_id': auth_user.id,
                'exp': datetime.now(timezone.utc) + timedelta(hours=2),
                'iat': datetime.now(timezone.utc)
            }
            token = jwt.encode(payload, settings.SECRET_KEY)
            return Response(data={'token': token, 'data': serializer.data, 'msg': '登录成功'},
                            status=status.HTTP_200_OK)
        except User.DoesNotExist:
            return Response(data={'detail': '账号不存在'}, status=status.HTTP_400_BAD_REQUEST)
